package test.file;

import static test.file.ReportProcessorConstant.ELEMENT_TYPE;
import static test.file.ReportProcessorConstant.ELEMENT_TYPE_METHOD;
import static test.file.ReportProcessorConstant.FILE_FULL_PATH;
import static test.file.ReportProcessorConstant.FULL_NAME;
import static test.file.ReportProcessorConstant.LINE_NO;
import static test.file.ReportProcessorConstant.METHOD_NAME;
import static test.file.ReportProcessorConstant.RELATIVE_FILE_PATH;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.bag.HashBag;
import org.apache.commons.io.FileUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.google.common.base.Joiner;

public class ReportReaderA implements ReportInfoReader {
	@Override
	public List<Map> readReport(File file, String encoding, String rootPath) throws IOException {
		List<Map> result = new ArrayList<>();
		String rawContent = FileUtils.readFileToString(file, encoding);
		String[] split = rawContent.split("\r\n|\r|\n");
		System.out.println("长度:" + split.length);
		
		//匹配方法信息
		Pattern regex = Pattern.compile("(com\\.[^(]+)\\(.*\\.java:([^)]+)\\)\\s+("+ELEMENT_TYPE_METHOD+")");
		Matcher matcher = regex.matcher(rawContent);
		while (matcher.find()) {
			Map map = new HashMap<>();
			// String fullName = matcher.group(0);
			//// System.out.println(fullName);
			// String fullName1 = matcher.group(1);
			// System.out.println("1");
			// System.out.println(fullName1);
			// String fullName2 = matcher.group(2);
			// System.out.println("2");
			// System.out.println(fullName2);
			// fullName
			System.out.println("Full Qualified Name: ");
			String fullName = matcher.group(1);
			map.put(FULL_NAME, fullName);
			System.out.println(fullName);
			// method name
			System.out.println("Method Name: ");
			String methodName = fullName.substring(fullName.lastIndexOf(".") + 1, fullName.length());
			System.out.println(methodName);
			map.put(METHOD_NAME, methodName);
			// relative path
			String filePath = File.separator + fullName.substring(0, fullName.lastIndexOf(".")).replaceAll("\\.", File.separator) + ".java";
			System.out.println(filePath);
			map.put(RELATIVE_FILE_PATH, filePath);
			// line no.
			String lineNo = matcher.group(2);
			System.out.println(lineNo);
			map.put(LINE_NO, lineNo);
			// element type 
			String elementType = matcher.group(3);
			System.out.println(elementType);
			map.put(ELEMENT_TYPE, elementType);
			
			result.add(map);
			System.out.println("");
		}
		return result;
	}

	@Override
	public MultiValueMap<String, String> orgnizeReport(List<Map> readReport,String rootPath) {
		MultiValueMap<String, String> fileMthodAndPos = new LinkedMultiValueMap<>(); // 文件里面的方法名和行号
		MultiValueMap<String, String> fileMthods = new LinkedMultiValueMap<>();// 文件里面的方法名
		for (Iterator iterator = readReport.iterator(); iterator.hasNext();) {
			Map map = (Map) iterator.next();
			String filePath = rootPath + map.get(RELATIVE_FILE_PATH);
			File file = new File(filePath);
			String methodName = (String) map.get(METHOD_NAME);
			String lineNo = (String) map.get(LINE_NO);
			String elementType = (String) map.get(ELEMENT_TYPE);
			fileMthodAndPos.add(filePath, Joiner.on("$").join(methodName,lineNo,elementType));
			fileMthods.add(filePath, methodName);
		}
		// 遍历每一个文件的所有方法,打印重复名称的方法
		System.out.println("Duplicate name Method: ");
		Iterator<String> iterator = fileMthods.keySet().iterator();
		while (iterator.hasNext()) {
			String key = (String) iterator.next();
			List<String> list = fileMthods.get(key);
			HashBag methodBag = new HashBag(list);
			HashSet methodSet = new HashSet(list);
			for (Iterator iterator2 = methodSet.iterator(); iterator2.hasNext();) {
				Object object = (Object) iterator2.next();
				int count = methodBag.getCount(object);
				if (count > 1) {
					System.out.println(object);
				}
			}
		}
		return fileMthodAndPos;
	}
}
